package manegement;

import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


/**
 * Class responsible for all the operations
 * @author Anne Lorayne, Laura Dutra, Francisco Otavio
 *
 */
public class BlogSystem {
	
	private BlogPathTree pathTree;
	private UserManager allUsers;
	private Map<String, String> loggedUsers;
	private static BlogSystem instance = new BlogSystem();
	

	/**
	 * Private constructor - Singleton.
	 */
	private BlogSystem() {
		loggedUsers = new HashMap<String, String>();
		allUsers = new UserManager();
		
		
	}
	
	/**
	 * Destructor
	 */
	public void finalize(){
		loggedUsers.clear();

	}
	
	/**
	 * Singleton.
	 * 
	 * @return A BlogSystem Instance
	 */
	public static synchronized BlogSystem getInstance() {
		if (instance == null)
			instance = new BlogSystem();
		return instance;

	}
	

	/**
	 * Capturing today's date and returns the format dd/MM/yyyy
	 * @return today's date
	 */
	public String todaysDate() {
		Date data = new Date(System.currentTimeMillis());
		SimpleDateFormat formatarDate = new SimpleDateFormat("dd/MM/yyyy");
		return formatarDate.format(data);
	}

	/**
	 * Allows one user to access the system
	 * 
	 * @param login
	 *            - User's login
	 * @param password
	 *            - User's password
	 * @return SessionID - Its must be unique.
	 * @throws Throws
	 *             exception if given user or password does not match. Or if
	 *             given users is already logged in.
	 */
	public String login(String login, String password) throws Exception {

		String userId = allUsers.getUserIdByLogin(login);
		
		if(loggedUsers.containsValue(userId))
			throw new Exception("Usuário já logado");
		
		if(userId == null || !allUsers.getInformationProfile(userId, "Password").equals(password))
			throw new Exception("Login ou senha inválido");
		
		String sessionId = newSessionId();
		loggedUsers.put(sessionId, userId);
		
		return sessionId;
	}

	/**
	 * Performs a logout of a given SessionID
	 * 
	 * @param sessionID
	 *            - The session which wants to be finished
	 * @return true if the logout was successful, false otherwise.
	 * @throws Exception
	 *             - Throws exception if given sessionID is not a valid one.
	 */
	public boolean logout(String sessionID) throws Exception {
		if (!(loggedUsers.containsKey(sessionID)))
			throw new Exception("Sessão inválida");
		loggedUsers.remove(sessionID);
		return true;
	}
	
	//User Operations

	/**
	 * 
	 * Create a new user.
	 * 
	 * @param login
	 *            - User's login
	 * @param password
	 *            - Users's password
	 * @param name
	 *            - User's name
	 * @param email
	 *            - Users's email
	 * @param gender
	 *            - Users's gender
	 * @param dateOfBirth
	 *            - User's dateOfBirth
	 * @param address
	 *            - User's address
	 * @param interests
	 *            - User's interests
	 * @param whoIAm
	 *            - User's whoIAm
	 * @param movies
	 *            - User's movies preferences
	 * @param musics
	 *            - User's musics preferences
	 * @param books
	 *            - User's books preferences
	 * @return TODO add returns comments
	 * @throws Exception
	 *             TODO add excp comments
	 */
	// TODO CHECAR STRING->CALENDAR
	// TODO CHECAR ENUM(GENDER)->STRING
	public void createUser(String login, String password, String name,
			String email, String gender, String dateOfBirth, String address,
			String interests, String whoIAm, String movies, String musics,
			String books) throws Exception {
		
		allUsers.createUser(login, password, name, email, gender, dateOfBirth, address, interests, whoIAm, movies, musics, books);
	}

	/**
	 * Changes a profile on system based on a given SessionID
	 * 
	 * @param sessionID
	 * @param attribute
	 * @param newValue
	 * @throws Exception
	 */
	public void changeProfileInformation(String sessionId, String attribute,
			String newValue) throws Exception {
		if (!(loggedUsers.containsKey(sessionId)))
			throw new Exception("Sessão inválida");
		String userId = loggedUsers.get(sessionId);
		allUsers.changeProfileInformation(userId, attribute, newValue);
	}
	
	/**
	 * Retrieves a users attribute value
	 * 
	 * @param login
	 *            - User's login
	 * @param attribute
	 *            - Attribute which you wants to know value
	 * @throws Exception
	 *             - Throwns exceptions if given att is invalid
	 */
	public String getInformationProfileBySessionId(String sessionId,
			String attribute) throws Exception {
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessao invalida");
		return allUsers.getInformationProfile(loggedUsers.get(sessionId), attribute);
	}
	
	/**
	 * Retrieves a users attribute value
	 * 
	 * @param login
	 *            - User's login
	 * @param attribute
	 *            - Attribute which you wants to know value
	 * @throws Exception
	 *             - Throwns exceptions if given att is invalid
	 */
	public String getInformationProfile(String login, String attribute)
	throws Exception {
		String userId = allUsers.getUserIdByLogin(login);
		return allUsers.getInformationProfile(userId, attribute);
	}

	
	/**
	 * Delete a profile
	 * @param sessionId
	 * @throws Exception
	 */
	public void deleteProfile(String sessionId) throws Exception {
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
			
		allUsers.deleteProfile(loggedUsers.get(sessionId));
		loggedUsers.remove(sessionId);

	}
	

	//Blog Operations
	/**
	 * Creates a new blog on system
	 * 
	 * @param sessionID
	 *            - Must be a valid ID to create a blog
	 * @param title
	 *            - Blog's title
	 * @param description
	 *            - Blog's description
	 * @return blogID
	 * @throws Exception
	 *             If not given a valid sessionID throws exception
	 */
	public String createBlog(String sessionId, String title, String description)
	throws Exception {
		if (!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
		return allUsers.createBlog(loggedUsers.get(sessionId),title, description);
	}
	
	/**
	 * Changes a blog on system based on a given SessionID
	 * 
	 * @param sessionID
	 * @param blogID
	 * @param attribute
	 * @param newValue
	 * @throws Exception
	 */
	public void changeBlogInformation(String sessionId, String blogId,
			String attribute, String newValue) throws Exception {
		
		//TODO If time: fix that
		if (attribute == null || attribute.equals(""))
			throw new Exception("Atributo inválido");
		
		if (!(loggedUsers.containsKey(sessionId)))
			throw new Exception("Sessão inválida");
		
		if (attribute.equals("titulo")
				&& (newValue == null || newValue.equals("")))
			throw new Exception("Você deve especificar um título para o blog");
		
		BlogPath path = pathTree.getBlogPath(blogId);
		
		if(path.getUserId() == null)
			throw new Exception("Blog invalido");
		
		if(!path.getUserId().equals(loggedUsers.get(sessionId)))
			throw new Exception("Sessão inválida");
		
		allUsers.changeBlogInformation(path.getUserId(), blogId, attribute, newValue);

	}
	
	/**
	 * Delete a blog
	 * @param sessionId
	 * 			- Identifier of the session to validate the User logon
	 * @param blogId
	 * 			- Identifier of the blog will be deleted
	 * @throws Exception
	 */
	public void deleteBlog(String sessionId, String blogId) throws Exception{
		BlogPath path = pathTree.getBlogPath(blogId);
		if(loggedUsers.containsKey(sessionId))
			if(loggedUsers.get(sessionId).equals(path.getUserId()))
				allUsers.deleteBlog(path.getUserId(), blogId);
	}


	
	/**
	 * Retrieves a blog attribute value
	 * 
	 * @param blogID
	 * @param attribute
	 *            - Attribute which you wants to know value
	 * @return attribute value
	 * @throws Exception
	 *             - Throwns exceptions if given att is invalid
	 */
	public String getInformationBlog(String blogId, String attribute)
	throws Exception {
		BlogPath path = pathTree.getBlogPath(blogId);
		
		return allUsers.getBlogInformation(path.getUserId(), blogId, attribute);
	}
	/**
	 * Returns the number of blogs login passed as parameter
	 * @param login
	 * @return number of blogs
	 */
	public int getNumberOfBlogsByLogin(String login) {
		String userId = allUsers.getUserIdByLogin(login);
		if(userId == null)
			return 0;
		return allUsers.getNumberOfBlogs(userId);
			
	}
		
	
	/**
	 * Returns the number if blogs sessionId passed as parameter
	 * @param sessionId
	 * @return number of blogs
	 */
	public int getNumberOfBlogsBySessionId(String sessionId) {
		if(loggedUsers.containsKey(sessionId))
			return allUsers.getNumberOfBlogs(loggedUsers.get(sessionId));
		return 0;
	}

	/**
	 * Returns the identifier of the blog of the session passed as parameter to index the past too.
	 * @param sessionId
	 * @param index
	 * @return blogId
	 * @throws Exception
	 */
	public String getBlogBySessionId(String sessionId, int index) throws Exception {
		if(loggedUsers.containsKey(sessionId)){
			return allUsers.getBlog(loggedUsers.get(sessionId), index);
		}
		throw new Exception("Sessao inválida");
	}

	/**
	 * Returns the identifier of the blog of the login passed as parameter to index the past too.
	 * @param login
	 * @param index
	 * @return blogId
	 * @throws Exception
	 */
	public String getBlogByLogin(String login, int index) throws Exception {
		String userId = allUsers.getUserIdByLogin(login);
		if(userId != null){
			return allUsers.getBlog(userId, index);
		}
	    throw new Exception("Login inválido");
	}



	//Post Operations
	/**
	 * Creare a new post
	 * @param sessionId
	 * @param blogId
	 * @param title
	 * @param text
	 * @return postId
	 * @throws Exception
	 */
	public String createPost(String sessionId, String blogId, String title,
			String text) throws Exception {
		
		BlogPath path = pathTree.getBlogPath(blogId);
		if(!loggedUsers.containsKey(sessionId) || !loggedUsers.get(sessionId).equals(path.getUserId()) && path.getUserId() != null)
			throw new Exception("Sessão inválida");
									
		return allUsers.createPost(path.getUserId(), blogId, title, text, todaysDate());
	
	}
	
	/**
	 * Retrieves a post attribute value
	 * 
	 * @param postID
	 * @param attribute
	 *            - Attribute which you wants to know value
	 * @return attribute value
	 * @throws Exception
	 *             - Throwns exceptions if given att is invalid
	 */
	public String getPostInformation(String postId, String attribute)
		throws Exception {
		
		BlogPath path = pathTree.getPostPath(postId);
		
		return allUsers.getPostInformation(path.getUserId(), path.getBlogId(), postId, attribute); 
	}
	
	/**
	 * Delete a post
	 * @param sessionId
	 * 			- Identifier of the session to validate the User logon
	 * @param postId
	 * 			- Identifier of the post will be deleted 
	 * @throws Exception
	 */
	public void deletePost(String sessionId, String postId) throws Exception {
		
		BlogPath path = pathTree.getPostPath(postId);
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
		
		allUsers.deletePost(path.getUserId(), path.getBlogId(), postId);
	}
	
	/**
	 * Capturing the post with the index passed as parameter
	 * @param blogId
	 * 			- Identifier of the blog which will capture the post
	 * @param index
	 * 			- Post's index
	 * @return postId
	 */
	public String getPost(String blogId, int index) {
		BlogPath path = pathTree.getBlogPath(blogId);
		if(path.getUserId() == null)
			return "";
		return allUsers.getPost(path.getUserId(), path.getBlogId(), index);
	}

	/**
	 * Modifies the information of the post passed as parameter
	 * @param sessionId
	 * 			- Identifier of the session to validate the User logon
	 * @param postId
	 * 			- Identifier of the post modification
	 * @param attribute
	 * 			- Attribute to be modified
	 * @param value
	 * 			- Value that will be inserted
	 * @throws Exception
	 */
	public void changePostInformation(String sessionId, String postId,
			String attribute, String value) throws Exception {
		BlogPath path = pathTree.getPostPath(postId);	
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
		if(path.getUserId() == null)
			throw new Exception("Post inválido");
		if(attribute == null)
			throw new Exception("Atributo inválido");
		
		allUsers.changePostInformation(path.getUserId(), path.getBlogId(), postId, attribute, value);
	}


	//Media operations
	/**
	 * Attaches a sound
	 * @param sessionID
	 * 			- Identifier of the session to validate the User logon
	 * @param postID
	 * 			- Identifier of the post that will be inserted audio
	 * @param description
	 * 			- Sound's description
	 * @param data
	 * 			- Data's sound
	 * @return soundId
	 *          - Identifier of the sound
	 * @throws Exception
	 */
	public String attachSound(String sessionId, String postId,
			String description, String data) throws Exception {
		if(data == null || data.equals(""))
			throw new Exception("Dado inválido");
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
		
		BlogPath path = pathTree.getPostPath(postId);
		
		return allUsers.attachSound(path.getUserId(), path.getBlogId(), postId, description, data);
	}

	/**
	 * Attaches a movie
	 * @param sessionID
	 * 			- Identifier of the session to validate the User logon
	 * @param postID
	 * 			- Identifier of the post that will be inserted sound
	 * @param description
	 * 			- Movie's description
	 * @param data
	 * 			- Data's movie
	 * @return moviedId
	 *          - Identifier of the movie
	 * @throws Exception
	 */
	public String attachMovie(String sessionId, String postId,
			String description, String data) throws Exception {
		if(data == null || data.equals(""))
			throw new Exception("Dado inválido");
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
		
		BlogPath path = pathTree.getPostPath(postId);
		
		return allUsers.attachMovie(path.getUserId(), path.getBlogId(), postId, description, data);
	}

	/**
	 * Attaches a picture
	 * @param sessionID
	 * 			- Identifier of the session to validate the User logon
	 * @param postID
	 * 			- Identifier of the post that will be inserted picture
	 * @param description
	 * 			- Picture's description
	 * @param data
	 * 			- Data's picture
	 * @return pictureId
	 *          - Identifier of the picture
	 * @throws Exception
	 */
	public String attachPicture(String sessionId, String postId,
			String description, String data) throws Exception {
		if(data == null || data.equals(""))
			throw new Exception("Dado inválido");
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
		
		BlogPath path = pathTree.getPostPath(postId);
		
		return allUsers.attachSound(path.getUserId(), path.getBlogId(), postId, description, data);

	}

	/**
	 * Returns the number of sounds from post
	 * @param postId
	 * 			- Identifier of the post sounds to be counted
	 * @return number of sounds
	 * @throws Exception
	 */
	public long getNumberOfSoundsOfPost(String postId) throws Exception {
		BlogPath path = pathTree.getPostPath(postId);
		if(path.getUserId() == null)
			throw new Exception("Post inválido");
		return allUsers.getNumberOfSoundsOfPost(path.getUserId(), path.getBlogId(), postId);
	}

	/**
	 * Returns the number of pictures from post
	 * @param postId
	 * 			- Identifier of the post pictures to be counted
	 * @return number of pictures
	 * @throws Exception
	 */
	public long getNumberOfPicturesOfPost(String postId) throws Exception {
		BlogPath path = pathTree.getPostPath(postId);
		if(path.getUserId() == null)
			throw new Exception("Post inválido");
		return allUsers.getNumberOfPicturesOfPost(path.getUserId(), path.getBlogId(), postId);
	}
	
	/**
	 * Returns the number of movies from post
	 * @param postId
	 * 			- Identifier of the post movies to be counted
	 * @return number of movies
	 * @throws Exception
	 */
	public long getNumberOfMoviesOfPost(String postId) throws Exception {
		BlogPath path = pathTree.getPostPath(postId);
		if(path.getUserId() == null)
			throw new Exception("Post inválido");
		return allUsers.getNumberOfMoviesOfPost(path.getUserId(), path.getBlogId(), postId);
		
	}
	
	/**
	 * Capturing the sound of the post with the index passed as parameter
	 * @param postId
	 * 			- Identifier of the post which will capture the sound
	 * @param index
	 * 			- Sound's index
	 * @return soundId
	 * @throws Exception
	 */
	public String getSound(String postId, int index) throws Exception {
		if(index < 0 || index > getNumberOfSoundsOfPost(postId))
			throw new Exception("Índice inválido");
		BlogPath path = pathTree.getPostPath(postId);
		if(path.getUserId() == null)
			throw new Exception("Post inválido");
		return allUsers.getSound(path.getUserId(), path.getBlogId(), postId, index);

	}
	
	/**
	 * Capturing the movie of the post with the index passed as parameter
	 * @param postId
	 * 			- Identifier of the post which will capture the movie
	 * @param index
	 * 			- Movie's index
	 * @return movieId
	 * @throws Exception
	 */
	public String getMovie(String postId, int index) throws Exception {
		if(index < 0 || index > getNumberOfMoviesOfPost(postId))
			throw new Exception("Índice inválido");
		BlogPath path = pathTree.getPostPath(postId);
		if(path.getUserId() == null)
			throw new Exception("Post inválido");
		return allUsers.getMovie(path.getUserId(), path.getBlogId(), postId, index);
	}
	
	/**
	 * Capturing the picture of the post with the index passed as parameter
	 * @param postId
	 * 			- Identifier of the post which will capture the picture
	 * @param index
	 * 			- Picture's index
	 * @return pictureId
	 * @throws Exception
	 */
	public String getPicture(String postId, int index) throws Exception {
		if(index < 0 || index >= getNumberOfPicturesOfPost(postId))
			throw new Exception("Índice incorreto");
		BlogPath path = pathTree.getPostPath(postId);
		if(path.getUserId() == null)
			throw new Exception("Post inválido");
		return allUsers.getPicture(path.getUserId(), path.getBlogId(), postId, index);

	}

	
	/**
	 * Returns data of sound
	 * @param soundId
	 * @return data of sound
	 * @throws Exception 
	 */
	public String getSoundData(String mediaId) throws Exception{
		BlogPath path = pathTree.getMediaPath(mediaId);
		if(path.getUserId() == null)
			throw new Exception("Audio inválido");
		return allUsers.getSoundData(path.getUserId(), path.getBlogId(), path.getPostId(), mediaId);
	}
	
	/**
	 * Returns description of sound
	 * @param soundId
	 * @return description of sound
	 * @throws Exception 
	 */
	public String getSoundDescription(String mediaId) throws Exception{
		BlogPath path = pathTree.getMediaPath(mediaId);
		if(path.getUserId() == null)
			throw new Exception("Audio inválido");
		return allUsers.getSoundDescription(path.getUserId(), path.getBlogId(), path.getPostId(), mediaId);
		
	}
	
	/**
	 * Returns data of movie
	 * @param movieId
	 * @return data of movie
	 * @throws Exception 
	 */
	public String getMovieData(String mediaId) throws Exception{
		BlogPath path = pathTree.getMediaPath(mediaId);
		if(path.getUserId() == null)
			throw new Exception("Video inválido");
		return allUsers.getMovieData(path.getUserId(), path.getBlogId(), path.getPostId(), mediaId);
	}
	
	/**
	 * Returns description of sound
	 * @param soundId
	 * @return description of sound
	 * @throws Exception 
	 */
	public String getMovieDescription(String mediaId) throws Exception{
		BlogPath path = pathTree.getMediaPath(mediaId);
		if(path.getUserId() == null)
			throw new Exception("Video inválido");
		return allUsers.getMovieDescription(path.getUserId(), path.getBlogId(), path.getPostId(), mediaId);
	}
	/**
	 * Returns data of picture
	 * @param pictureId
	 * @return data of picture
	 * @throws Exception 
	 */
	public String getPictureData(String mediaId) throws Exception{
		BlogPath path = pathTree.getMediaPath(mediaId);
		if(path.getUserId() == null)
			throw new Exception("Imagem inválido");
		return allUsers.getPictureData(path.getUserId(), path.getBlogId(), path.getPostId(), mediaId);
	}
	
	/**
	 * Returns description of sound
	 * @param soundId
	 * @return description of sound
	 * @throws Exception 
	 */
	public String getPictureDescription(String mediaId) throws Exception{
		BlogPath path = pathTree.getMediaPath(mediaId);
		if(path.getUserId() == null)
			throw new Exception("Imagem inválido");
		return allUsers.getPictureDescription(path.getUserId(), path.getBlogId(), path.getPostId(), mediaId);
	}

	//Comment Operations
	/**
	 * Add a comment
	 * @param sessionId
	 * 			- Identifier of the session to validate the User logon
	 * @param postId
	 * 			- identifier of the post which is inserted into the comment
	 * @param comment
	 * 			- Text's comment
	 * @return
	 * @throws Exception
	 */
	public String addComment(String sessionId, String postId, String comment) throws Exception {
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
		
		BlogPath path = pathTree.getPostPath(postId);
		if(path.getUserId() == null)
			throw new Exception("Post inválido");
		
		return allUsers.addComment(path.getUserId(), path.getBlogId(), path.getPostId(), comment,
				allUsers.getInformationProfile(loggedUsers.get(sessionId), "Login"));
	}


	//US7

	/**
	 * Returns the number of blog posts
	 * @param blogId
	 * @return number of posts
	 * @throws Exception
	 */
	public int getNumberOfPosts(String blogId) throws Exception{
		BlogPath path = pathTree.getBlogPath(blogId);
		if(path.getUserId() == null)
			throw new Exception("Blog inválido");
		return allUsers.getNumberOfPosts(path.getUserId(), blogId);
	}

	/**
	 * Delete a movie
	 * @param sessionId
	 * 			- Identifier of the session to validate the User logon
	 * @param movieId
	 * 			- Identifier of the movie will be deleted
	 */
	public void deleteMovie(String sessionId, String movieId) {
		BlogPath path = pathTree.getMediaPath(movieId);
		if(loggedUsers.containsKey(sessionId))
			if(loggedUsers.get(sessionId).equals(path.getUserId()))
				allUsers.deleteMovie(path.getUserId(), path.getBlogId(), path.getPostId(),movieId);
	}
	
	/**
	 * Delete a sound
	 * @param sessionId
	 * 			- Identifier of the session to validate the User logon
	 * @param soundId
	 * 			- Identifier of the sound will be deleted
	 */
	public void deleteSound(String sessionId, String soundId) {
		BlogPath path = pathTree.getMediaPath(soundId);
		if(loggedUsers.containsKey(sessionId))
			if(loggedUsers.get(sessionId).equals(path.getUserId()))
				allUsers.deleteSound(path.getUserId(), path.getBlogId(), path.getPostId(),soundId);
		
	}

	/**
	 * Delete a picture
	 * @param sessionId
	 * 			- Identifier of the session to validate the User logon
	 * @param pictureId
	 * 			- Identifier of the picture will be deleted
	 */
	public void deletePicture(String sessionId, String pictureId) {
		BlogPath path = pathTree.getMediaPath(pictureId);
		if(loggedUsers.containsKey(sessionId))
			if(loggedUsers.get(sessionId).equals(path.getUserId()))
				allUsers.deletePicture(path.getUserId(), path.getBlogId(), path.getPostId(),pictureId);
	}

	/**
	 * Returns the number of comments of post
	 * @param postId
	 * 			- Identifier of the post which will capture the number of comments
	 * @return number of posts
	 * @throws Exception
	 */
	public long getNumberOfComments(String postId) throws Exception {
		
		BlogPath path = pathTree.getPostPath(postId);
		if(path.getUserId() == null)
			throw new Exception("Post inválido");
		
		return allUsers.getNumberOfComments(path.getUserId(), path.getBlogId(), postId); 
	}

	
	/**
	 * Capturing the comment with the index passed as parameter
	 * @param postId
	 * 			- Identifier of the post which will capture the comment
	 * @param index
	 * 			- comment's index
	 * @return commentId
	 */
	public String getComment(String postId, int index) throws Exception {
		BlogPath path = pathTree.getPostPath(postId);
		if(path.getUserId() == null)
			throw new Exception("Post inválido");
		
		return allUsers.getComment(path.getUserId(), path.getBlogId(), postId, index); 
	}
	
	/**
	 * Retrieves the comment's text passed as parameter
	 * @param commentId
	 * 			- identifier of the comment that the text will be recovered
	 * @return comment's text
	 * @throws Exception
	 */
	public String getCommentText(String commentId) throws Exception {
		BlogPath path = pathTree.getCommentPath(commentId);
		if(path.getUserId() == null)
			throw new Exception("Comentario inválido");
		
		return allUsers.getCommentText(path.getUserId(), path.getBlogId(), path.getPostId(), commentId); 
	}

	/**
	 * Retrieves the comment's author passed as parameter
	 * @param commentId
	 * 			- identifier of the comment that the author will be recovered
	 * @return comment's author
	 * @throws Exception
	 */
	public String getCommentAuthor(String commentId) throws Exception {
		BlogPath path = pathTree.getCommentPath(commentId);
		if(path.getUserId() == null)
			throw new Exception("Comentario inválido");
		
		return allUsers.getCommentAuthor(path.getUserId(), path.getBlogId(), path.getPostId(), commentId); 
	}
	
	
	//TODO Busca
	/**
	 * Returns the number of comments of login and blogId
	 * @param login
	 * @param blogId
	 * @return number of comments
	 */
	public int getNumberOfComments(String login, String blogId) {
		BlogPath path = pathTree.getBlogPath(blogId);
		if(allUsers.getUserIdByLogin(login) == null || path.getUserId() == null)
			return 0;
		return allUsers.getNumberOfCommentsByLogin(path.getUserId(), blogId, login);
		
	}

	//US12

	/**
	 * Returns a list of profile by name
	 * @param match
	 * @return list of profile
	 * @throws Exception
	 */
	public List<String> findProfileByName(String match) throws Exception{
		List<String> users = allUsers.findProfileByName(match);
		Collections.sort(users);
		return users;
	}

	/**
	 * Returns a list of profile by interests
	 * @param match
	 * @return list
	 * @throws Exception
	 */
	public List<String> findProfileByInterests(String match) throws Exception {
		
		List<String> users = allUsers.findProfileByInterests(match);
		Collections.sort(users);
		return users;
	}
	
	/**
	 * Returns a list of profile by gender
	 * @param match
	 * @return list
	 * @throws Exception
	 */
	public List<String> findProfileByGender(String match) throws Exception {
		List<String> users = allUsers.findProfileByGender(match);		
		Collections.sort(users);
		return users;
	}

	/**
	 * Returns a list of blog by name passed as parameter
	 * @param match
	 * @return list
	 * @throws Exception
	 */
	public List<String> findBlogByName(String match) throws Exception {
		return allUsers.findBlogByName(match);
	}
	
	//TODO
	//US13

	/**
	 * Returns a number of announcements by sessionId passed as parameter
	 * @param sessionId
	 * @return number of announcements
	 * @throws Exception
	 */
	public int getNumberOfAnnouncements(String sessionId) throws Exception {
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
//TODO		return loggedUsers.get(sessionId).getNumberOfAnnouncements();
		return 0;
	}

	/**
	 * Add a post announcement
	 * @param sessionId
	 * @param blogId
	 * @throws Exception
	 */
	public void addPostAnnouncements(String sessionId, String blogId) throws Exception {
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
//TODO		loggedUsers.get(sessionId).addPostAnnouncements(blogId);
		
	}

	/**
	 * Returns the id of announcement
	 * @param sessionId
	 * @param index
	 * @return announcementId
	 * @throws Exception
	 */
	public String getAnnouncement(String sessionId, int index) throws Exception {
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
		
		if(index < 0 || index >= getNumberOfAnnouncements(sessionId))
			throw new Exception("Índice inválido");
//TODO Implement that		
//		return loggedUsers.get(sessionId).getAnnouncement(index);
		return null;
	}

	/**
	 * Returns a post just created with announcementId passed as parameter
	 * @param announcementId
	 * @return
	 */
	public String getPostJustCreated(String announcementId) {
//		User user;
//		String blogId = null;
//		for (Iterator<User> it = allUsers.iterator(); it.hasNext();) {
//			user = it.next();
//			if(user.hasAnnouncement(announcementId)){
//				blogId = user.getAnnouncementBlogId(announcementId);
//			}
//		}
//		
//		for (Iterator<User> it = allUsers.iterator(); it.hasNext();) {
//			user = it.next();
//			if(user.hasBlog(blogId)){
//				try{
//					return user.getPostAtIndex(blogId, 0);
//				}catch (Exception e) {
//					return null;
//				}
//			}
//		}
//	
		return null;
	}

	/**
	 * Delete a announcement
	 * @param sessionId
	 * @param announcementId
	 * @throws Exception
	 */
	public void deleteAnnouncement(String sessionId, String announcementId) throws Exception {
//TODO
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessão inválida");
//		loggedUsers.get(sessionId).deleteAnnouncement(announcementId);
	}
	
	//US14

	/**
	 * Create a sub blog
	 * @param sessionId
	 * @param blogId
	 * @param title
	 * @param description
	 * @return subblogId
	 * @throws Exception
	 */
	public String createSubBlog(String sessionId, String blogId, String title,
			String description) throws Exception{
		
		BlogPath path = pathTree.getBlogPath(blogId);
		
		if (!(loggedUsers.containsKey(sessionId)) )
			throw new Exception("Sessão inválida");
				
		if(path.getUserId() == null)
			throw new Exception("Blog invalido");
		
		if(!loggedUsers.get(sessionId).equals(path.getUserId()))
			throw new Exception("Sessão inválida");
		
		return allUsers.createSubBlog(path.getUserId(), blogId, title, description);
	}
	

	/**
	 * Returns the number of sub blogs
	 * @param blogId
	 * @return number of sub blogs
	 * @throws Exception
	 */
	public int getNumberOfSubBlogs(String blogId) throws Exception{
		BlogPath path = pathTree.getBlogPath(blogId);
		if(path.getUserId() == null)
			throw new Exception("Blog invalido");
		return allUsers.getNumberOfSubBlogs(path.getUserId(), blogId);
	}

	/**
	 * Returns the number of all sub blogs
	 * @param blogId
	 * @return number of all sub blogs
	 * @throws Exception
	 */
	public int getNumberOfAllSubBlogs(String blogId) throws Exception{
		BlogPath path = pathTree.getBlogPath(blogId);
		if(path.getUserId() == null)
			throw new Exception("Blog invalido");
		return allUsers.getNumberOfAllSubBlogs(path.getUserId(), blogId);
	}

	/**
	 * Returns the id of sub blog of blog passed as parameter
	 * @param blogId
	 * @param index
	 * @return subBlogId
	 * @throws Exception
	 */
	public String getSubBlog(String blogId, int index) throws Exception{
		BlogPath path = pathTree.getBlogPath(blogId);
		if(path.getUserId() == null)
			throw new Exception("Blog invalido");
		return allUsers.getSubBlog(path.getUserId(), blogId, index);
	}

	/**
	 * Returns the number of all posts of blog passed as parameter
	 * @param blogId
	 * @return number of all posts
	 * @throws Exception
	 */
	public int getNumberOfAllPosts(String blogId) throws Exception {
		BlogPath path = pathTree.getBlogPath(blogId);
		return allUsers.getNumberOfAllPosts(path.getUserId(), blogId);
		}

	public String addSubComment(String sessionId, String commentId, String texto) throws Exception{
		if(!loggedUsers.containsKey(sessionId))
			throw new Exception("Sessao invalida");
		BlogPath path = pathTree.getCommentPath(commentId);
		if(path.getUserId() == null)
			throw new Exception("Comentario invalido");
		if(!path.getUserId().equals(loggedUsers.get(sessionId))){
			throw new Exception("Sessao invalida");
		}
		return allUsers.addSubComment(path.getUserId(), path.getBlogId(), path.getPostId(), commentId, texto);
	}

	public String getSubComment(String commentId, int index) throws Exception {
		BlogPath path = pathTree.getCommentPath(commentId);
		return allUsers.getSubComment(path.getUserId(), path.getBlogId(), path.getPostId(), commentId, index);
	}

	public int getNumberOfSubComments(String commentId) throws Exception {
		BlogPath path = pathTree.getCommentPath(commentId);
		return allUsers.getNumberOfSubComments(path.getUserId(), path.getBlogId(), path.getPostId(), commentId);
	}

	public int getNumberOfAllSubComments(String commentId) {
		BlogPath path = pathTree.getCommentPath(commentId);
		return allUsers.getNumberOfAllSubComments(path.getUserId(), path.getBlogId(), path.getPostId(), commentId);
	}
	
	private String newSessionId(){
		return Long.toString(System.currentTimeMillis());
	}


	
}
